package com.credit.mola.app.ui.process.page

import android.annotation.SuppressLint
import android.graphics.Typeface
import android.text.SpannableString
import android.text.Spanned
import android.text.style.ForegroundColorSpan
import android.text.style.StyleSpan
import android.view.LayoutInflater
import android.view.View
import androidx.core.content.ContextCompat
import androidx.lifecycle.lifecycleScope
import androidx.recyclerview.widget.DefaultItemAnimator
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import com.credit.mola.app.R
import com.credit.mola.app.adapter.ProcessCommonAdapter
import com.credit.mola.app.databinding.PageProcessCommonBinding
import com.credit.mola.app.pro.ProFragment
import com.credit.mola.app.ui.process.activity.ProcessActivity
import com.credit.mola.app.utils.DensityUtils
import com.credit.mola.app.utils.config.Configs
import com.credit.mola.app.utils.dialog.BirthdayDialog
import com.credit.mola.app.utils.dialog.CommonPopupWindow
import com.credit.mola.app.utils.event.EventType
import com.credit.mola.app.utils.event.track.TrackEventManager
import com.credit.mola.app.utils.helper.ActivityStackHelper
import com.credit.mola.app.utils.http.AppUrls
import com.credit.mola.app.utils.http.AppUrls.addCommonParams
import com.credit.mola.app.utils.http.IHttpCallback
import com.credit.mola.app.utils.log.HHLog
import com.credit.mola.app.utils.rv.LinearDecoration
import com.credit.mola.lib_baseadapter.SikadwaBaseAdapterUtil.getColor
import com.credit.mola.lib_baseadapter.SikadwaOnItemChildClickListener
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
import org.greenrobot.eventbus.EventBus
import org.greenrobot.eventbus.Subscribe
import org.greenrobot.eventbus.ThreadMode
import org.json.JSONArray
import org.json.JSONObject

/**
 * Sikadwa
 * @Author wwdeng
 * @CreateTime: 2024/4/18 11:29
 * @Annotation：流程通用列表样式
 */
class CommonPage(): ProFragment() {
    private var _binding: PageProcessCommonBinding? = null
    private val binding get() = _binding ?: throw IllegalStateException(
        "Cannot access binding because it is null. Either the view hasn't been created yet, or it has already been destroyed."
    )
    var data: JSONObject? = null

    //内容列表
    var mCommonAdapter: ProcessCommonAdapter? = null
    var mSelectPosition = -1

    //出生日期选择
    private var mBirthdayDialog: BirthdayDialog? = null

    constructor(data: JSONObject): this(){
        this.data = data
        HHLog.e(">>>>>>>>>>>>>>>>>>>>>>>>>>$data")
    }

    override fun getRootView(inflater: LayoutInflater): View {
        _binding = PageProcessCommonBinding.inflate(inflater)
        return binding.root
    }

    override fun initView() {
        rootViewBinding.containerLayout.setBackgroundColor(ContextCompat.getColor(requireContext(),R.color.transparent))
        initRvList()
        EventBus.getDefault().register(this)
    }

    override fun initListener() {
        //下一步
        _binding?.btnNext?.setOnClickListener {
            onMolaSubProcessDataAction()
        }
    }

    override fun initData() {
        if (data == null){
            ActivityStackHelper.finishActivity(ProcessActivity::class.java)
            return
        }

        _binding?.stepTipsLayout?.visibility = View.GONE
        _binding?.contactAddOne?.visibility = View.INVISIBLE
        _binding?.approvedTipsLayout?.visibility = View.GONE
        // TODO: 2025.09.12 下一步按钮常驻底部，在ProcessActivity显示
        _binding?.btnNext?.visibility = View.GONE
        data?.let {
            val stepTitle = it.optString("stepTitle")
            if ("personal_info" == stepTitle){
                _binding?.textStepTips?.setTextColor(getColor(R.color.FF4C8FFB))
                val showKey = getString(R.string.process_personal_info_tips_key)
                val showText = String.format(getString(R.string.process_personal_info_tips),showKey)
                val startIndex = showText.indexOf(showKey)
                val dataSecuritySpannable = SpannableString(showText)
                dataSecuritySpannable.setSpan(ForegroundColorSpan(getColor(R.color.FF0040A8)), startIndex, startIndex + showKey.length, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE)
                //加粗
                dataSecuritySpannable.setSpan(StyleSpan(Typeface.BOLD), startIndex, startIndex + showKey.length, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE)
                _binding?.textStepTips?.text = dataSecuritySpannable
                _binding?.stepTipsIcon?.setImageResource(R.mipmap.img_process_personal_info_tips_icon)
                _binding?.stepTipsLayout?.setBackgroundResource(R.drawable.process_personal_info_tips_bg)
                _binding?.stepTipsLayout?.visibility = View.VISIBLE
            }

            val dataList = arrayListOf<JSONObject>()
            val dataArray = it.optJSONArray("dataList")
            if (dataArray != null) {
                for (i in 0..< dataArray.length()){
                    dataList.add(dataArray.optJSONObject(i))
                }
            }
            addEvent(String.format(EventType.PAGE.PAGE_STEP_COMMON_XX_START,it.optString("stepTitle")),"")

            //安哥拉 && 工作信息 - 包含发薪日 默认显示
            if ("work_info" == stepTitle){
                for (item in dataList) {
                    //发薪日
                    if (item.optString("paramName") == "salaryDay"){
                        item.put("isShowItem",false)
                    }
                }
            }
            mCommonAdapter?.data = dataList
        }
    }

    /**
     * 初始化页面内容列表
     */
    private fun initRvList() {
        _binding?.rvCommon?.setHasFixedSize(true)
        _binding?.rvCommon?.isNestedScrollingEnabled = false
        _binding?.rvCommon?.isFocusableInTouchMode = false //不需要焦点
        val layoutManager = LinearLayoutManager(context)
        layoutManager.orientation = RecyclerView.VERTICAL
        _binding?.rvCommon?.layoutManager = layoutManager
        val topDecoration = DensityUtils.dp2px(14f)
        _binding?.rvCommon?.addItemDecoration(LinearDecoration(0, 0, 0, topDecoration))
        mCommonAdapter = ProcessCommonAdapter(_binding?.rvCommon)
        _binding?.rvCommon?.adapter = mCommonAdapter
        _binding?.rvCommon?.itemAnimator = DefaultItemAnimator()
        mCommonAdapter?.setOnItemChildClickListener(onItemClickListener)
    }

    /**
     * 选择
     */
    private val onItemClickListener = SikadwaOnItemChildClickListener { _, childView, position ->
            _binding?.root?.clearFocus()
            mSelectPosition = position
            mCommonAdapter?.let { adapter ->
                val item = adapter.getItem(position)
                when (item.optString("action")) {
                    "DATE_PICK" -> {//出生日期选择
                        showBirthDialog()
                        item.put("showError",false)
                        adapter.notifyItemChanged(position)
                    }
                    "SELECT",
                    "GENDER_PICK",
                    "SALARY_DAY_PICK" -> {//普通选择、性别、发薪日
                        val dataList = arrayListOf<JSONObject>()
                        val dataArray = item.optJSONArray("values")
                        dataArray?.let {
                            for (i in 0..<it.length()) {
                                dataList.add(it.optJSONObject(i))
                            }
                        }
                        showSelectPopupwindow(childView, dataList)
                    }
                    "BANK_PICK" -> {//安哥拉 - 选择银行
                        showCmAngolaChooseBank(childView,item)
                    }
                }
            }
        }

    /**
     * 安哥拉 - 工作信息中选择发薪日
     * 逻辑：
     *     当工资支付频率为月结（salaryFrequency -> Monthly salary）时，发薪日选择1-31
     *     当工资支付频率为周结（salaryFrequency -> Weekly salary）时，发薪日选择周一至周日
     *     当工资支付频率为其它（salaryFrequency -> Others）时，发薪日不显示
     */
    private fun formatCmSalaryDayPick(adapter: ProcessCommonAdapter,item: JSONObject){
        val selectValue = item.optString("selectValue")

        val salaryDayArray = JSONArray()
        var isMust = "YES"

        if (selectValue.startsWith("Monthly")){ //月结
            isMust = "YES"
            //发薪日 1-31
            for (i in 1..31){
                val obj = JSONObject()
                obj.put("title","$i")
                obj.put("value","$i")
                salaryDayArray.put(obj)
            }
        } else if (selectValue.startsWith("Weekly")){  //周结
            isMust = "YES"
            //发薪日 周一 - 周日
            val weekTitleList = arrayListOf(R.string.week1,R.string.week2,R.string.week3,R.string.week4,R.string.week5,R.string.week6,R.string.week7)
            val weekValueList = arrayListOf("Monday","Tuesday","Wednesday","Thursday","Friday","Saturday","Sunday")
            for (i in 0 until weekTitleList.size){
                val obj = JSONObject()
                obj.put("title",getString(weekTitleList[i]))
                obj.put("value", weekValueList[i])
                salaryDayArray.put(obj)
            }
        } else { //Others
            isMust = "NO"
        }
        for (i in 0 until adapter.itemCount){
            val model = adapter.getItem(i)
            if (model.optString("paramName") == "salaryDay"){
                model.put("isShowItem",isMust == "YES")
                model.put("isMust",isMust)
                model.put("values",salaryDayArray)
                model.put("selectItem",null)
                adapter.notifyItemChanged(i)
            }
        }
    }

    /**
     * 安哥拉 - 绑卡选择银行
     */
    private fun showCmAngolaChooseBank(view: View,item: JSONObject){
        val dataArray = item.optJSONArray("values")
        if (dataArray == null || dataArray.length() == 0){
            loadCmBindCardBankListAction(view,item)
            return
        }
        val dataList = arrayListOf<JSONObject>()
        dataArray.let {
            for (i in 0..<it.length()) {
                dataList.add(it.optJSONObject(i))
            }
        }
        showSelectPopupwindow(view, dataList)
    }

    /**
     * 选择选项
     */
    private fun showSelectPopupwindow(view: View,dataList: ArrayList<JSONObject>){
        _binding?.let {
            val selectPopup = CommonPopupWindow(requireContext())
            selectPopup.setWindowWidth(view.width + DensityUtils.dp2px(10f))
            selectPopup.setSelectItemListener(object : CommonPopupWindow.IItemClickListener {
                //完成
                override fun onConfirmAction(data: JSONObject) {
                    mCommonAdapter?.let { adapter ->
                        val item = adapter.getItem(mSelectPosition)
                        item.put("selectItem",data)
                        val selectValue = data.optString("value")

                        /**
                         * 安哥拉 - 工作信息 - 发薪频率
                         */
                        if (item.optString("paramName") == "salaryFrequency"){
                            item.put("selectValue",selectValue)
                            //选择发信频率后，需要更新发薪日的选项
                            formatCmSalaryDayPick(adapter,item)
                        }
                        adapter.notifyItemChanged(mSelectPosition)

                        val subRemark = "${selectValue}$$${data.optString("duration")}"
                        addEvent(String.format(EventType.CLICK.CLICK_STEP_XX_SELECT,item.optString("paramName")),subRemark)
                    }
                }
                //关闭监听
                override fun onDismissListener() {
                }
            })
            selectPopup.show(view, it.root)
            selectPopup.setBrandList(dataList)
        }

        mCommonAdapter?.let { adapter ->
            val item = adapter.getItem(mSelectPosition)
            item.put("showError",false)
            adapter.notifyItemChanged(mSelectPosition)
        }
    }

    /**
     * 选择出生日期
     */
    private fun showBirthDialog(){
        if (mBirthdayDialog == null){
            mBirthdayDialog = BirthdayDialog(context,"",object : BirthdayDialog.IDialogCallback{
                override fun completed(selectDate: JSONObject) {
                    mCommonAdapter?.let {
                        //可根据需要自行截取数据显示
                        val item = it.getItem(mSelectPosition)
                        val obj = JSONObject()
                        obj.put("title",selectDate.optString("showDate"))
                        obj.put("value",selectDate.optString("subDate"))
                        item.put("selectItem",obj)
                        it.notifyItemChanged(mSelectPosition)

                        addEvent(String.format(EventType.CLICK.CLICK_STEP_XX_SELECT,item.optString("paramName")),selectDate.optString("subDate"))
                    }
                }
            })
        }
        mBirthdayDialog?.show()
    }

    /**
     * 检查是否填写完整
     * 当且仅当 isMust=”NO“为非必填
     */
    private fun isAllowSubmit(): Boolean{
        //是否允许提交
        var isAllow = true
        mCommonAdapter?.let { adapter ->
            for (i in 0..< adapter.itemCount){
                val item = adapter.getItem(i)
                //存在 isMust && isMust == ”NO“  非必填
                if (item.has("isMust") && item.optString("isMust") == "NO"){
                    continue
                }
                //必填 && 没有内容 || 内容为空
                if (!item.has("selectItem")){
                    isAllow = false
                    break
                }
                val selectItem = item.optJSONObject("selectItem")
                if (selectItem == null){
                    isAllow = false
                    break
                }
                if (selectItem.optString("value","").isEmpty()){
                    isAllow = false
                    break
                }
            }
        }
        return isAllow
    }

    /**
     * 提交数据
     */
    @SuppressLint("NotifyDataSetChanged")
    private fun onMolaSubProcessDataAction(){
        _binding?.root?.clearFocus()
        if (!isAllowSubmit() || data == null){
            showToast(getString(R.string.tips_submit_error))
            mCommonAdapter?.let { adapter ->
                for (i in 0 until adapter.itemCount){
                    val item = adapter.getItem(i)
                    val isMust = item.optString("isMust") == "YES"
                    if (!isMust){
                        continue
                    }
                    val selectItem = item.optJSONObject("selectItem")
                    //必填 && 没填/选
                    if (selectItem == null){
                        item.put("showError",true)
                        adapter.notifyItemChanged(i)
                        continue
                    }
                    if (selectItem.optString("value","").isEmpty()){
                        item.put("showError",true)
                        adapter.notifyItemChanged(i)
                        continue
                    }
                }
            }
            return
        }

        data?.let {
            val params = JSONObject().addCommonParams().apply {
                put("path",it.optString("apiUrl").replace("/",""))
            }
            mCommonAdapter?.let { adapter ->
                for (i in 0..< adapter.itemCount){
                    val item = adapter.getItem(i)
                    if (item.has("selectItem")){
                        val selectItem = item.optJSONObject("selectItem")
                        if (selectItem != null){
                            params.put(item.optString("paramName"),selectItem.optString("value"))
                        }
                    }
                }
            }
            //立即上报
            TrackEventManager.trackEventNow(String.format(EventType.CLICK.CLICK_STEP_XX_NEXT,it.optString("stepTitle")),"")

            HHLog.e(">>>>>>提交数据>>>>>>>$params")
            val act = context as ProcessActivity
            act.submitAction(params)
        }
    }

    @Subscribe(threadMode = ThreadMode.POSTING)
    fun onRefreshedProcess(event: String){
        when(event){
            Configs.Event.PROCESS_DATA_SUB -> {//上级点击提交
                onMolaSubProcessDataAction()
            }
        }
    }

    /**
     * 获取收款账户类型列表
     */
    private fun loadCmBindCardBankListAction(view: View,item: JSONObject) {
        showLoading()
        val httpUrl = AppUrls.getHttpUrl(AppUrls.URL.COMMON)
        val params = JSONObject().addCommonParams().apply {
            put("path",AppUrls.PATH.BIND_CARD_BANK_LIST)
        }
        postAction(httpUrl,params,object : IHttpCallback{
            override fun onRequestSuccess(data: JSONObject) {
                val dataArray = data.optJSONArray("obj")
                dataArray?.let {
                    for (i in 0 until dataArray.length()){
                        val obj = dataArray.optJSONObject(i)
                        obj.put("title",obj.optString("bankName"))
                        obj.put("value",obj.optString("bankName"))
                    }
                    item.put("values",dataArray)
                    lifecycleScope.launch {
                        delay(300)
                        showCmAngolaChooseBank(view,item)
                    }
                }
            }
            override fun onRequestError(error: JSONObject) {
            }
            override fun onRequestFinish() {
            }
        })
    }

    override fun onDestroy() {
        super.onDestroy()
        EventBus.getDefault().unregister(this)
        data?.let {
            addEvent(String.format(EventType.PAGE.PAGE_STEP_COMMON_XX_END,it.optString("stepTitle")),"")
        }
    }

    override fun onDestroyView() {
        super.onDestroyView()
        _binding = null
    }
}